GtkWidget *window;
GtkWidget *widget_tree;
GtkWidget *prop_list;
+ GtkWidget *child_prop_list;
GtkWidget *python_shell;
GtkWidget *button_path;
GtkWidget *classes_list;
enum
{
PROP_0,
- PROP_WIDGET_TREE
+ PROP_WIDGET_TREE,
+ PROP_CHILD_PROPERTIES
};
struct _ParasitePropListPrivate
GList *signal_cnxs;
GtkWidget *widget_tree;
GtkTreeViewColumn *property_column;
+ GtkTreeViewColumn *value_column;
+ gboolean child_properties;
};
G_DEFINE_TYPE_WITH_PRIVATE (ParasitePropList, parasite_proplist, GTK_TYPE_TREE_VIEW)
g_object_set (renderer,
"scale", TREE_TEXT_SCALE,
"editable", TRUE,
+ "is-child-property", pl->priv->child_properties,
NULL);
- column = gtk_tree_view_column_new_with_attributes ("Value", renderer,
- "text", COLUMN_VALUE,
- "object", COLUMN_OBJECT,
- "name", COLUMN_NAME,
- NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (pl), column);
- gtk_tree_view_column_set_resizable (column, TRUE);
+ pl->priv->value_column = gtk_tree_view_column_new_with_attributes ("Value", renderer,
+ "text", COLUMN_VALUE,
+ "object", COLUMN_OBJECT,
+ "name", COLUMN_NAME,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (pl), pl->priv->value_column);
+ gtk_tree_view_column_set_resizable (pl->priv->value_column, TRUE);
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (pl->priv->model),
COLUMN_NAME,
GTK_SORT_ASCENDING);
- gtk_tree_view_column_set_cell_data_func (column,
+ gtk_tree_view_column_set_cell_data_func (pl->priv->value_column,
renderer,
(GtkTreeCellDataFunc) draw_columns,
pl,
g_value_take_object (value, pl->priv->widget_tree);
break;
+ case PROP_CHILD_PROPERTIES:
+ g_value_set_boolean (value, pl->priv->child_properties);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
pl->priv->widget_tree = g_value_get_object (value);
break;
+ case PROP_CHILD_PROPERTIES:
+ pl->priv->child_properties = g_value_get_boolean (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
"Widget tree",
GTK_TYPE_WIDGET,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class, PROP_CHILD_PROPERTIES,
+ g_param_spec_boolean ("child-properties", "Child properties", "Child properties",
+ FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
static void
char *value;
g_value_init(&gvalue, prop->value_type);
- g_object_get_property (pl->priv->object, prop->name, &gvalue);
+ if (pl->priv->child_properties)
+ {
+ GtkWidget *parent;
+
+ parent = gtk_widget_get_parent (GTK_WIDGET (pl->priv->object));
+ gtk_container_child_get_property (GTK_CONTAINER (parent),
+ GTK_WIDGET (pl->priv->object),
+ prop->name, &gvalue);
+ }
+ else
+ g_object_get_property (pl->priv->object, prop->name, &gvalue);
if (G_VALUE_HOLDS_ENUM (&gvalue))
{
gtk_list_store_set (pl->priv->model, iter,
COLUMN_NAME, prop->name,
- COLUMN_VALUE, value,
+ COLUMN_VALUE, value ? value : g_strdup (""),
COLUMN_DEFINED_AT, g_type_name (prop->owner_type),
COLUMN_OBJECT, pl->priv->object,
COLUMN_TOOLTIP, g_param_spec_get_blurb (prop),
}
GtkWidget *
-parasite_proplist_new (GtkWidget *widget_tree)
+parasite_proplist_new (GtkWidget *widget_tree,
+ gboolean child_properties)
{
return g_object_new (PARASITE_TYPE_PROPLIST,
"widget-tree", widget_tree,
+ "child-properties", child_properties,
NULL);
}
g_hash_table_remove_all (pl->priv->prop_iters);
gtk_list_store_clear (pl->priv->model);
- props = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &num_properties);
+ if (pl->priv->child_properties)
+ {
+ GtkWidget *parent;
+
+ if (!GTK_IS_WIDGET (object))
+ return;
+
+ parent = gtk_widget_get_parent (GTK_WIDGET (object));
+ if (!parent)
+ return;
+
+ props = gtk_container_class_list_child_properties (G_OBJECT_GET_CLASS (parent), &num_properties);
+ }
+ else
+ props = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &num_properties);
+
for (i = 0; i < num_properties; i++)
{
GParamSpec *prop = props[i];
g_hash_table_insert (pl->priv->prop_iters, (gpointer) prop->name, gtk_tree_iter_copy (&iter));
/* Listen for updates */
- signal_name = g_strdup_printf ("notify::%s", prop->name);
+ if (pl->priv->child_properties)
+ signal_name = g_strdup_printf ("child-notify::%s", prop->name);
+ else
+ signal_name = g_strdup_printf ("notify::%s", prop->name);
pl->priv->signal_cnxs =
g_list_prepend (pl->priv->signal_cnxs, GINT_TO_POINTER(
G_BEGIN_DECLS
GType parasite_proplist_get_type (void);
-GtkWidget *parasite_proplist_new (GtkWidget *widget_tree);
+GtkWidget *parasite_proplist_new (GtkWidget *widget_tree,
+ gboolean child_properties);
void parasite_proplist_set_object (ParasitePropList *proplist,
GObject *object);
{
GObject *object;
char *name;
+ gboolean is_child_property;
};
enum
{
PROP_0,
PROP_OBJECT,
- PROP_NAME
+ PROP_NAME,
+ PROP_IS_CHILD_PROPERTY
};
G_DEFINE_TYPE_WITH_PRIVATE (ParasitePropertyCellRenderer, parasite_property_cell_renderer, GTK_TYPE_CELL_RENDERER_TEXT);
g_value_set_string(value, r->priv->name);
break;
+ case PROP_IS_CHILD_PROPERTY:
+ g_value_set_boolean (value, r->priv->is_child_property);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
r->priv->name = g_value_dup_string (value);
break;
+ case PROP_IS_CHILD_PROPERTY:
+ r->priv->is_child_property = g_value_get_boolean (value);
+ g_object_notify (object, "is-child-property");
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
}
}
+static GParamSpec *
+find_property (GtkCellRenderer *renderer)
+{
+ ParasitePropertyCellRenderer *r = PARASITE_PROPERTY_CELL_RENDERER (renderer);
+
+ if (r->priv->is_child_property)
+ {
+ GtkWidget *parent;
+
+ parent = gtk_widget_get_parent (GTK_WIDGET (r->priv->object));
+
+ return gtk_container_class_find_child_property (G_OBJECT_GET_CLASS (parent), r->priv->name);
+ }
+
+ return g_object_class_find_property (G_OBJECT_GET_CLASS (r->priv->object), r->priv->name);
+}
+
+static void
+get_value (GtkCellRenderer *renderer,
+ GValue *gvalue)
+{
+ ParasitePropertyCellRenderer *r = PARASITE_PROPERTY_CELL_RENDERER (renderer);
+
+ if (r->priv->is_child_property)
+ {
+ GtkWidget *widget;
+ GtkWidget *parent;
+
+ widget = GTK_WIDGET (r->priv->object);
+ parent = gtk_widget_get_parent (widget);
+
+ gtk_container_child_get_property (GTK_CONTAINER (parent), widget, r->priv->name, gvalue);
+ }
+ else
+ g_object_get_property (r->priv->object, r->priv->name, gvalue);
+}
+
+static void
+set_value (GtkCellRenderer *renderer,
+ GValue *gvalue)
+{
+ ParasitePropertyCellRenderer *r = PARASITE_PROPERTY_CELL_RENDERER (renderer);
+
+ if (r->priv->is_child_property)
+ {
+ GtkWidget *widget;
+ GtkWidget *parent;
+
+ widget = GTK_WIDGET (r->priv->object);
+ parent = gtk_widget_get_parent (widget);
+
+ gtk_container_child_set_property (GTK_CONTAINER (parent), widget, r->priv->name, gvalue);
+ }
+ else
+ g_object_set_property (r->priv->object, r->priv->name, gvalue);
+}
+
static void
stop_editing(GtkCellEditable *editable, GtkCellRenderer *renderer)
{
- GObject *object;
- const char *name;
GValue gvalue = {0};
GParamSpec *prop;
- object = g_object_get_data(G_OBJECT(editable), "_prop_object");
- name = g_object_get_data(G_OBJECT(editable), "_prop_name");
-
- prop = g_object_class_find_property(G_OBJECT_GET_CLASS(object), name);
+ prop = find_property (renderer);
g_value_init(&gvalue, prop->value_type);
if (GTK_IS_ENTRY(editable))
}
}
- g_object_set_property(object, name, &gvalue);
+ set_value (renderer, &gvalue);
g_value_unset(&gvalue);
}
{
PangoFontDescription *font_desc;
GtkCellEditable *editable = NULL;
- GObject *object;
- const char *name;
GValue gvalue = {0};
GParamSpec *prop;
+ ParasitePropertyCellRenderer *r = PARASITE_PROPERTY_CELL_RENDERER (renderer);
- g_object_get(renderer,
- "object", &object,
- "name", &name,
- NULL);
+ prop = find_property (renderer);
- prop = g_object_class_find_property(G_OBJECT_GET_CLASS(object), name);
g_value_init(&gvalue, prop->value_type);
- g_object_get_property(object, name, &gvalue);
+
+ get_value (renderer, &gvalue);
if (G_VALUE_HOLDS_OBJECT (&gvalue))
{
{
parasite_widget_tree_select_object (widget_tree, prop_object);
}
- else if (parasite_widget_tree_find_object (widget_tree, object, &iter))
+ else if (parasite_widget_tree_find_object (widget_tree, r->priv->object, &iter))
{
parasite_widget_tree_append_object (widget_tree, prop_object, &iter);
parasite_widget_tree_select_object (widget_tree, prop_object);
pango_font_description_free(font_desc);
g_signal_connect(editable, "editing_done", G_CALLBACK (stop_editing), renderer);
- g_object_set_data_full (G_OBJECT (editable), "_prop_name", g_strdup (name), g_free);
- g_object_set_data (G_OBJECT (editable), "_prop_object", object);
return editable;
}
"The property name",
NULL,
G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_IS_CHILD_PROPERTY,
+ g_param_spec_boolean ("is-child-property", "Child property", "Child property",
+ FALSE, G_PARAM_READWRITE));
}
GtkCellRenderer *
if (selected != NULL)
{
- parasite_proplist_set_object (PARASITE_PROPLIST (parasite->prop_list),
- selected);
- parasite_objecthierarchy_set_object (PARASITE_OBJECTHIERARCHY (parasite->oh),
- selected);
+ parasite_proplist_set_object (PARASITE_PROPLIST (parasite->prop_list), selected);
+ parasite_proplist_set_object (PARASITE_PROPLIST (parasite->child_prop_list), selected);
+ parasite_objecthierarchy_set_object (PARASITE_OBJECTHIERARCHY (parasite->oh), selected);
if (GTK_IS_WIDGET (selected))
{
}
static GtkWidget *
-create_prop_list_pane(ParasiteWindow *parasite)
+create_prop_list_pane (ParasiteWindow *parasite,
+ gboolean child_properties)
{
GtkWidget *swin;
+ GtkWidget *pl;
swin = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
"hscrollbar-policy", GTK_POLICY_AUTOMATIC,
"width-request", 250,
NULL);
- parasite->prop_list = parasite_proplist_new (parasite->widget_tree);
- gtk_container_add(GTK_CONTAINER(swin), parasite->prop_list);
+ pl = parasite_proplist_new (parasite->widget_tree, child_properties);
+ gtk_container_add (GTK_CONTAINER (swin), pl);
+
+ if (child_properties)
+ parasite->child_prop_list = pl;
+ else
+ parasite->prop_list = pl;
return swin;
}
"show-border", FALSE,
NULL);
gtk_notebook_append_page (GTK_NOTEBOOK (nb),
- create_prop_list_pane (window),
- gtk_label_new ("GObject Properties"));
+ create_prop_list_pane (window, FALSE),
+ gtk_label_new ("Properties"));
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (nb),
+ create_prop_list_pane (window, TRUE),
+ gtk_label_new ("Child Properties"));
window->oh = parasite_objecthierarchy_new ();
gtk_notebook_append_page (GTK_NOTEBOOK (nb),